﻿using PmSadis.Repositories.Abstract;
using PmSadis.Models;
using System.Linq;
using System;
using System.Data.Entity;
using PmSadis.UsersDal;
using WebMatrix.WebData;
using System.Web;
using System.Collections.Generic;
using System.Web.Security;
using System.Threading.Tasks;

namespace PmSadis.Repositories
{
    /// <summary>
    /// Хранилище пользователей
    /// </summary>
    public class SadisUserRepository
    {
        private UsersContext _context = new UsersContext();
        private SimpleMembershipProvider _simpleMembershipProvider;
        private SimpleRoleProvider _simpleRoleProvider;

        public SadisUserRepository()
        {
            _simpleMembershipProvider = (SimpleMembershipProvider)Membership.Provider;
            _simpleRoleProvider = (SimpleRoleProvider)Roles.Provider;
        }

        /// <summary>
        /// Полный список пользователей
        /// </summary>
        public IQueryable<SadisUser> All
        {
            get
            {
                return _context.SadisUsers.OrderBy(x => x.DisplayName);
            }
        }

        /// <summary>
        /// Удалить пользователя
        /// </summary>
        /// <param name="id">Идентификатор пользователя</param>
        public void Delete(object id)
        {
            var userId = (int)id;
            var user = _context.SadisUsers.FirstOrDefault(x => x.UserId == userId);
            if (user != null)
            {
                var roles = _simpleRoleProvider.GetRolesForUser(user.UserName);
                if (roles.Count() > 0)
                {
                    _simpleRoleProvider.RemoveUsersFromRoles(new string[] { user.UserName }, roles);
                }
                _simpleMembershipProvider.DeleteAccount(user.UserName);
                _simpleMembershipProvider.DeleteUser(user.UserName, true);
            }
        }

        /// <summary>
        /// Создать или редактировать пользователя
        /// </summary>
        /// <param name="user">Пользователь</param>
        /// <param name="password">Пароль (при создании пользователя)</param>
        /// <param name="roles">Роли пользователя</param>
        public object Edit(SadisUser user, string password = null, List<string> roles = null)
        {
            var dateNow = DateTime.Now;
            if (user.UserId == 0)
            {
                user.DateCreate = dateNow;
                user.DateUpdate = dateNow;
                _simpleMembershipProvider.CreateUserAndAccount(user.UserName, password, new Dictionary<string, object>() {
                    {"DATE_CREATE", user.DateCreate},
                    {"DATE_UPDATE", user.DateUpdate},
                    {"DISPLAY_NAME", user.DisplayName},
                    {"IS_GEN_CONTRACTOR", null}
                });
            }
            else
            {
                user.DateUpdate = dateNow;
                _context.Entry(user).State = EntityState.Modified;
            }
            
            roles = roles == null 
                ? null 
                : roles.Where(x => !string.IsNullOrEmpty(x)).ToList();

            if (roles != null && roles.Count != 0)
            {
                /*изменяем роли в отдельном потоке*/
                Task.Factory.StartNew(() =>
                {
                    var userRoles = GetRolesForUser(user.UserName).ToArray();
                    if (userRoles.Count() != 0)
                    {
                        _simpleRoleProvider.RemoveUsersFromRoles(new string[] { user.UserName }, userRoles);
                    }
                    _simpleRoleProvider.AddUsersToRoles(new string[] { user.UserName }, roles.ToArray());
                });
            }
            if (roles == null && GetRolesForUser(user.UserName).Count > 0)
            {
                Task.Factory.StartNew(() =>
                {
                    var userRoles = GetRolesForUser(user.UserName).ToArray();
                     _simpleRoleProvider.RemoveUsersFromRoles(new string[] { user.UserName }, userRoles);
                });
            }

            _context.SaveChanges();

            return user.UserId;
        }

        /// <summary>
        /// Все роли приложения
        /// </summary>
        public List<string> AllRoles
        {
            get
            {
                return Roles.GetAllRoles().ToList();
            }
        }

        /// <summary>
        /// Роли пользоваиеля
        /// </summary>
        /// <param name="userName">Логин пользователя</param>
        /// <returns></returns>
        public List<string> GetRolesForUser(string userName)
        {
            return Roles.GetRolesForUser(userName).ToList();
        }
    }
}
